进程加载过程以及Linux进程内存分析
1、进程加载分析
进程的加载过程从bash调用fork()系统调用创建一个新进程开始,新进程调用execve()系统调用执行指定的ELF文件,在执行execve()后,内核就开始了真正的装载过程,execvp()系统调用对应的入口是sys_execve(),在sys_execve()进行了一些参数的检查复制后,调用do_execve(),之后do_execve()会找到指定的ELF文件,读取前128个字节用于判断文件的格式和类型,之后调用search_binary_handle()去搜索匹配合适的可执行文件装载处理过程,search_binary_handle()通过ELF文件的魔数确定文件的格式,调用相应的装载处理方式,ELF的装载处理过程称为load_elf_binary(),a.out的叫load_aout_binary(),装载可执行脚本的叫做load_script()。这里介绍load_elf_binary()。
load_elf_binary()过程如下:
- 检查ELF文件格式的有效性,如魔数,段的数量
- 寻找动态链接的.interp段,设置动态链接路径。
- 根据ELF可执行文件的描述,对ELF文件进行映射,如代码,数据,只读数据。
- 初始化ELF进程环境,比如进程启动是的edx寄存器的地址应该是DT_FINI的地址
- 将系统调用的返回地址修改为ELF可执行文件的入口点,对于ELF可执行文件,入口点就是e_entry指向的地址,动态链接的ELF文件的入口点是动态链接器。
当load_elf_binary()执行完后,返回至do_execve(),再返回到sys_execve()时,第五步已经把系统调用的返回地址改成了被装在的ELF程序的入口地址了。所以当sys_execve()系统调用从内核态返回到用户态是,eip寄存器就直接跳转到ELF程序的入口地址了,新的程序开始执行,ELF文件装载完毕。
2、进程内存分析
对与ELF文件的映射,涉及到内存的问题,着重分析一下。